﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ImageTour
{
    public partial class NewSceneForm : Form
    {
        private ImageAnnotationTool curTool;
        private ImageAnnotation annotation = new ImageAnnotation();

        private void SetTool(ImageAnnotationTool tool)
        {
            curTool = tool;
            tool.Init(imgView, annotation);
        }

        public NewSceneForm(Bitmap bmp)
        {
            InitializeComponent();
            imgView.SetImage(bmp);
            imgView.ViewMode = ViewMode.BestFit;
            SetTool(new LineAnnotationTool());
            txtFocalLen_TextChanged(this, EventArgs.Empty);
            txtCamHeight_TextChanged(this, EventArgs.Empty);
            txtWallHeight_TextChanged(this, EventArgs.Empty);
        }

        private void imgView_DrawOverlay(Graphics g, Rectangle imageRect)
        {
            curTool.DrawOverlay(g);
        }

        private void imgView_ImageMouseDown(int x, int y)
        {
            curTool.MouseDown(x, y);
            imgView.RefreshOverlay();
        }

        private void imgView_ImageMouseMove(int x, int y)
        {
            curTool.MouseMove(x, y);
            imgView.RefreshOverlay();
        }

        private void imgView_ImageMouseUp(int x, int y)
        {
            curTool.MouseUp(x, y);
            imgView.RefreshOverlay();
        }

        private void parallelPairToolButton_Click(object sender, EventArgs e)
        {
            UncheckButtons();
            parallelPairToolButton.Checked = true;
            SetTool(new ParallelPairAnnotationTool());
        }

        private void baselineToolButton_Click(object sender, EventArgs e)
        {
            UncheckButtons();
            baselineToolButton.Checked = true;
            SetTool(new LineAnnotationTool());
        }

        private void txtFocalLen_TextChanged(object sender, EventArgs e)
        {
            if (float.TryParse(txtFocalLen.Text, out annotation.FocalLength))
                imgView.RefreshOverlay();
        }

        private void txtCamHeight_TextChanged(object sender, EventArgs e)
        {
            if (float.TryParse(txtCamHeight.Text, out annotation.CameraHeight))
                imgView.RefreshOverlay();
        }

        private void txtWallHeight_TextChanged(object sender, EventArgs e)
        {
            if (float.TryParse(txtWallHeight.Text, out annotation.WallHeight))
                imgView.RefreshOverlay();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (annotation.IsConsistent)
            {
                var mesh = annotation.ToMesh(imgView.Image);
                renderModel = new BackgroundModel(mesh);
                mesh.Dispose();
                DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            else
                MessageBox.Show("Please specify at least one pair of parallel lines.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        BackgroundModel renderModel;
        internal BackgroundModel RenderModel
        {
            get
            {
                return renderModel;
            }
        }

        internal PerspectiveTransformation Transform
        {
            get
            {
                return annotation.GetTransform(imgView.Image.Width, imgView.Image.Height);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        private void auxlineToolButton_Click(object sender, EventArgs e)
        {
            UncheckButtons();
            auxlineToolButton.Checked = true;
            SetTool(new LineAnnotationTool(true));
        }

        private void UncheckButtons()
        {
            foreach (var obj in toolStrip1.Items)
                if (obj is ToolStripButton)
                    (obj as ToolStripButton).Checked = false;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {

        }

        private void horizonToolButton_Click(object sender, EventArgs e)
        {
            SetTool(new HorizonTool());
            UncheckButtons();
            horizonToolButton.Checked = true;
        }
    }
}
